package org.sundayli;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ReplayingDecoder;
import java.util.List;
import org.sundayli.config.ConfigManager;

public class RedisCommandDecoder extends ReplayingDecoder<Void> {
  private static final byte cr = 13;
  private static final byte cn = 10;
  private ConfigManager configManager;

  public RedisCommandDecoder(ConfigManager configManager) {
    this.configManager = configManager;
  }


  @Override
  protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
    byte[] buf = new byte[configManager.getCommandMaxBufferLength()];
    buf[0] = in.readByte();
    int len = readLine(buf, in);
    String commandNumStr = new String(buf, 0, len);
    int num = parseNum(commandNumStr);
    while (num-- > 0) {
      buf[0] = in.readByte();
      len = readLine(buf, in);
      String commandLenStr = new String(buf, 0, len);
      int commandLen = parseNum(commandLenStr);
      String commandVale = readLine(buf, in, commandLen);
      System.out.println(commandVale);
    }
  }

  private int parseNum(String commandNumStr) {
    int num = 0;
    for (int i = 1; i < commandNumStr.length(); i++) {
      num = num * 10 + (commandNumStr.charAt(i) - '0');
    }
    return num;
  }

  private String readLine(byte[] buf, ByteBuf in, int len) {
    in.readBytes(buf, 0, len + 2);
    return new String(buf, 0, len);
  }

  private int readLine(byte[] buf, ByteBuf in) {
    int idx = 1;
    while (idx < buf.length) {
      buf[idx++] = in.readByte();
      if (buf[idx - 1] == cn && buf[idx - 2] == cr) break;
    }
    return idx - 2;
  }
}
